package jk.framework.spring.security.authorization;

import org.springframework.context.MessageSource;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.vote.AbstractAccessDecisionManager;
import org.springframework.security.access.vote.AffirmativeBased;
import org.springframework.security.access.vote.ConsensusBased;
import org.springframework.security.access.vote.UnanimousBased;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;

import java.util.Collection;
import java.util.List;

/**
 * 动态权限投票管理
 * @author cuichao
 */
@Deprecated
public class DynamicAccessDecisionManager extends AbstractAccessDecisionManager {

    /**
     * 一致决议器: 所有Voter一致通过才放行
     */
    private final UnanimousBased unanimous;
    /**
     * 共识决议器：大部分voter通过就放行
     */
    private final ConsensusBased consensus;
    /**
     * 肯定决议器: 只要有一个voter通过放行
     */
    private final AffirmativeBased affirmative;
    /**
     * 指定决议器
     */
    private final AccessDecisionManager decision;


    public DynamicAccessDecisionManager(List<AccessDecisionVoter<?>> decisionVoters) {
        super(decisionVoters);
        List<AccessDecisionVoter<?>> voters = super.getDecisionVoters();
        unanimous = new UnanimousBased(voters);
        consensus = new ConsensusBased(voters);
        affirmative = new AffirmativeBased(voters);
        decision = affirmative;
    }


    @Override
    public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {

        decision.decide(authentication, object, configAttributes);
    }

    @Override
    public void setAllowIfAllAbstainDecisions(boolean allowIfAllAbstainDecisions) {
        unanimous.setAllowIfAllAbstainDecisions(allowIfAllAbstainDecisions);
        consensus.setAllowIfAllAbstainDecisions(allowIfAllAbstainDecisions);
        affirmative.setAllowIfAllAbstainDecisions(allowIfAllAbstainDecisions);
        super.setAllowIfAllAbstainDecisions(allowIfAllAbstainDecisions);
    }


    @Override
    public void setMessageSource(MessageSource messageSource) {
        unanimous.setMessageSource(messageSource);
        consensus.setMessageSource(messageSource);
        affirmative.setMessageSource(messageSource);
        super.setMessageSource(messageSource);
    }
}

